<template>
  <div id="viewer" class="viewer-container"></div>
</template>

<script>
import { ref, onMounted, onUnmounted, watch } from 'vue'
import * as PhotoSphereViewer from '@photo-sphere-viewer/core'
import '@photo-sphere-viewer/core/index.css'
import { vrAPI } from '../services/api.js'

export default {
  name: 'VRViewer',
  emits: ['vr-point-changed'],
  setup(props, { emit }) {
    // 状态管理
    const viewer = ref(null)
    const vrData = ref(null)
    const currentIndex = ref(0)
    const currentPage = ref(1)
    const pageSize = ref(6)
    const totalItems = ref(0)
    
    // 预加载相关状态
    const preloadedImages = ref(new Map()) // 存储已预加载的图片
    const preloadQueue = ref([]) // 预加载队列
    const isPreloading = ref(false) // 是否正在预加载
    const preloadConcurrency = 2 // 预加载并发数
    const preloadDistance = 2 // 预加载当前索引前后多少张图片

    // 加载VR数据
    const loadVRData = async (pageNum, pageSize) => {
      try {
        const data = await vrAPI.getVRList(pageNum, pageSize)

        // 转换API返回的数据格式以匹配代码期望的结构
        vrData.value = {
          ...data,
          items: data.rows.map(item => ({
            ...item,
            pointVrId: item.id, // 映射 id 到 pointVrId
            imgUrl: item.panorama, // 映射 panorama 到 imgUrl
            title: item.name // 映射 name 到 title
          }))
        }

        totalItems.value = data.total || 0
        return data
      } catch (error) {
        console.error('加载VR数据失败:', error)
        showError('加载VR数据失败: ' + error.message)
        return null
      }
    }
    
    // 预加载单张图片
    const preloadImage = (url) => {
      return new Promise((resolve, reject) => {
        // 如果已经预加载过，则直接返回成功
        if (preloadedImages.value.has(url)) {
          resolve(url)
          return
        }
        
        const img = new Image()
        img.onload = () => {
          preloadedImages.value.set(url, true) // 标记为已加载
          resolve(url)
        }
        img.onerror = () => {
          console.warn(`图片预加载失败: ${url}`)
          reject(new Error(`Failed to preload image: ${url}`))
        }
        img.src = url
      })
    }
    
    // 处理预加载队列
    const processPreloadQueue = async () => {
      if (isPreloading.value || preloadQueue.value.length === 0) {
        return
      }
      
      isPreloading.value = true
      
      try {
        // 取出队列中最多preloadConcurrency个URL进行预加载
        const urlsToLoad = preloadQueue.value.splice(0, preloadConcurrency)
        const promises = urlsToLoad.map(url => preloadImage(url))
        
        await Promise.allSettled(promises)
        
        // 如果队列中还有待加载的URL，继续处理
        if (preloadQueue.value.length > 0) {
          await processPreloadQueue()
        }
      } catch (error) {
        console.error('处理预加载队列时出错:', error)
      } finally {
        isPreloading.value = false
      }
    }
    
    // 根据当前索引预加载相邻图片
    const preloadAdjacentImages = () => {
      if (!vrData.value || !vrData.value.items) {
        return
      }
      
      const items = vrData.value.items
      const startIndex = Math.max(0, currentIndex.value - preloadDistance)
      const endIndex = Math.min(items.length - 1, currentIndex.value + preloadDistance)
      
      // 预加载范围内的所有图片
      for (let i = startIndex; i <= endIndex; i++) {
        const item = items[i]
        const imgUrl = item.imgUrl || item.imageUrl
        
        // 如果图片URL存在且未在预加载队列中且未预加载过，则添加到队列
        if (imgUrl && !preloadQueue.value.includes(imgUrl) && !preloadedImages.value.has(imgUrl)) {
          preloadQueue.value.push(imgUrl)
        }
      }
      
      // 开始处理预加载队列
      processPreloadQueue()
    }
    
    // 清理预加载缓存（防止内存泄漏）
    const cleanupPreloadedImages = () => {
      if (!vrData.value || !vrData.value.items) {
        return
      }
      
      const currentUrls = new Set()
      const items = vrData.value.items
      
      // 保留当前页的图片和预加载范围内的图片
      const startIndex = Math.max(0, currentIndex.value - preloadDistance)
      const endIndex = Math.min(items.length - 1, currentIndex.value + preloadDistance)
      
      for (let i = startIndex; i <= endIndex; i++) {
        const item = items[i]
        const imgUrl = item.imgUrl || item.imageUrl
        if (imgUrl) {
          currentUrls.add(imgUrl)
        }
      }
      
      // 删除不在当前保留范围内的图片缓存
      preloadedImages.value.forEach((_, url) => {
        if (!currentUrls.has(url)) {
          preloadedImages.value.delete(url)
        }
      })
    }

    // 显示错误信息
    const showError = (message) => {
      // 移除现有的错误信息
      const existingError = document.querySelector('.error-message')
      if (existingError) {
        existingError.remove()
      }

      const errorDiv = document.createElement('div')
      errorDiv.className = 'error-message'
      errorDiv.innerHTML = `
        <h3>加载VR内容时出现问题</h3>
        <p>${message}</p>
        <button onclick="location.reload()" style="margin-top: 10px; padding: 8px 16px; background: #4ecdc4; border: none; border-radius: 4px; color: white; cursor: pointer;">重新加载</button>
      `
      document.body.appendChild(errorDiv)
    }

    // 设置查看器
    const setupViewer = async (item) => {
      try {
        const container = document.getElementById('viewer')
        if (!container) {
          throw new Error('查看器容器未找到')
        }

        // 销毁现有查看器
        if (viewer.value) {
          viewer.value.destroy()
        }

        const imgUrl = item.imgUrl || item.imageUrl
        
        // 如果图片已预加载，我们可以直接使用它
        // PhotoSphereViewer会自动使用浏览器缓存的图片
        console.log(`设置查看器: ${item.title}, 图片预加载状态: ${preloadedImages.value.has(imgUrl)}`)
        
        // 创建新的查看器
        viewer.value = new PhotoSphereViewer.Viewer({
          container: 'viewer',
          panorama: imgUrl,
          caption: item.title || '',
          loadingImg: '/qj/loding.png',
          defaultZoomLvl: 100,
          mousewheel: false,
          touchmoveTwoFingers: false,
          maxFov: 90,
          // 移除底部控制器和顶部导航栏
          navbar: false,
          // 移除自动旋转插件
          plugins: []
        })

        // 应用视角设置
        applyViewerSettings(item, viewer.value)

        // 监听查看器事件
        // setupViewerEvents()

        return viewer.value
      } catch (error) {
        console.error('设置查看器失败:', error)
        showError('初始化全景查看器失败: ' + error.message)
        return null
      }
    }

    // 应用视角设置
    const applyViewerSettings = (newItem, viewer) => {
      console.log('应用视角设置: ', {
        yaw: newItem.initialYaw,
        pitch: newItem.initialPitch,
        zoom: newItem.initialZoom
      })

      const animateOptions = {
        speed: 3000
      }

      // 确保值是有效的数字
      if (newItem.initialYaw !== undefined && typeof newItem.initialYaw === 'number' && !isNaN(newItem.initialYaw)) {
        animateOptions.yaw = newItem.initialYaw
      }
      if (newItem.initialPitch !== undefined && typeof newItem.initialPitch === 'number' && !isNaN(newItem.initialPitch)) {
        animateOptions.pitch = newItem.initialPitch
      }
      if (newItem.initialZoom !== undefined && typeof newItem.initialZoom === 'number' && !isNaN(newItem.initialZoom)) {
        animateOptions.zoom = newItem.initialZoom
      }

      // 检查是否有有效的参数需要设置
      const hasValidOptions = 'yaw' in animateOptions || 'pitch' in animateOptions || 'zoom' in animateOptions
      if (hasValidOptions) {
        console.log('执行视角动画: ', animateOptions)
        viewer.animate(animateOptions)
      }

      // 根据需求，初始化加载时不启动自动旋转
      // 如需手动启用旋转功能，可以在这里添加相应的控制逻辑
    }



    // 监听查看器事件
    const setupViewerEvents = () => {
      if (!viewer.value) return

      // 监听旋转事件
      viewer.value.addEventListener('position-updated', (e) => {
        console.log('位置更新:', e.position)
      })

      // 监听点击事件
      viewer.value.addEventListener('click', (e) => {
        console.log('点击位置:', e.data.position)
      })

      // 监听全景加载完成事件
      viewer.value.addEventListener('ready', () => {
        console.log('全景加载完成')
      })
    }

    // 加载上一页数据
    const loadPreviousPage = async () => {
      try {
        await loadVRData(currentPage.value - 1, pageSize.value)
        // 加载成功后，设置索引为新页面的最后一个项目
        currentIndex.value = vrData.value.items.length - 1
        await setupViewer(vrData.value.items[currentIndex.value])
        emit('vr-point-changed', {
          pointId: vrData.value.items[currentIndex.value].pointVrId,
          index: currentIndex.value,
          item: vrData.value.items[currentIndex.value]
        })
        
        // 加载新页面后预加载相邻图片
        preloadAdjacentImages()
      } catch (error) {
        console.error('加载上一页失败:', error)
        showError('加载上一页VR内容失败: ' + error.message)
      }
    }

    // 加载下一页数据
    const loadNextPage = async () => {
      try {
        await loadVRData(currentPage.value + 1, pageSize.value)
        // 加载成功后，设置索引为新页面的第一个项目
        currentIndex.value = 0
        await setupViewer(vrData.value.items[currentIndex.value])
        emit('vr-point-changed', {
          pointId: vrData.value.items[currentIndex.value].pointVrId,
          index: currentIndex.value,
          item: vrData.value.items[currentIndex.value]
        })
        
        // 加载新页面后预加载相邻图片
        preloadAdjacentImages()
      } catch (error) {
        console.error('加载下一页失败:', error)
        showError('加载下一页VR内容失败: ' + error.message)
      }
    }

    // 显示上一个VR
    const showPreviousVR = async () => {
      if (!vrData.value || !vrData.value.items || vrData.value.items.length === 0) {
        return
      }

      if (currentIndex.value > 0) {
        // 当前页还有上一个项目
        currentIndex.value--
        await setupViewer(vrData.value.items[currentIndex.value])
        emit('vr-point-changed', {
          pointId: vrData.value.items[currentIndex.value].pointVrId,
          index: currentIndex.value,
          item: vrData.value.items[currentIndex.value]
        })
        
        // 预加载新的相邻图片
        preloadAdjacentImages()
      } else if (currentPage.value > 1) {
        // 当前页没有上一个项目，但还有上一页
        await loadPreviousPage()
      }
    }

    // 显示下一个VR
    const showNextVR = async () => {
      if (!vrData.value || !vrData.value.items || vrData.value.items.length === 0) {
        return
      }

      if (currentIndex.value < vrData.value.items.length - 1) {
        // 当前页还有下一个项目
        currentIndex.value++
        await setupViewer(vrData.value.items[currentIndex.value])
        emit('vr-point-changed', {
          pointId: vrData.value.items[currentIndex.value].pointVrId,
          index: currentIndex.value,
          item: vrData.value.items[currentIndex.value]
        })
        
        // 预加载新的相邻图片
        preloadAdjacentImages()
      } else if (currentPage.value * pageSize.value < totalItems.value) {
        // 当前页没有下一个项目，但还有下一页
        await loadNextPage()
      }
    }

    // 根据ID显示VR
    const showVRById = async (pointVrId) => {
      if (!vrData.value || !vrData.value.items) {
        return
      }

      const index = vrData.value.items.findIndex(item => item.pointVrId === pointVrId)
      if (index !== -1) {
        currentIndex.value = index
        await setupViewer(vrData.value.items[index])
        emit('vr-point-changed', {
          pointId: pointVrId,
          index: index,
          item: vrData.value.items[index]
        })
        
        // 切换场景后预加载相邻图片
        preloadAdjacentImages()
      }
    }

    // 初始化查看器
    const initViewer = async () => {
      try {
        await loadVRData(currentPage.value, pageSize.value)

        if (!vrData.value || !vrData.value.items || vrData.value.items.length === 0) {
          console.log('没有获取到VR数据或数据格式不正确')
          showError('没有可用的VR内容，请检查网络连接或数据源')
          return null
        }

        // 初始化查看器并加载第一个VR项
        await setupViewer(vrData.value.items[0])
        emit('vr-point-changed', {
          pointId: vrData.value.items[0].pointVrId,
          index: 0,
          item: vrData.value.items[0]
        })
        
        // 初始化时预加载相邻图片
        preloadAdjacentImages()

        return viewer.value
      } catch (error) {
        console.error('查看器初始化失败:', error)
        showError('查看器初始化失败: ' + error.message)
        return null
      }
    }

    // 键盘导航处理
    const handleKeyDown = (e) => {
      if (!viewer.value) return

      switch (e.key) {
        case 'ArrowLeft':
          showPreviousVR()
          break
        case 'ArrowRight':
          showNextVR()
          break
      }
    }

    // 生命周期钩子
    onMounted(() => {
      initViewer().catch(error => {
        console.error('查看器初始化失败: ' + error.message)
      })
      // 添加键盘导航事件监听
      document.addEventListener('keydown', handleKeyDown)
    })

    onUnmounted(() => {
      if (viewer.value) {
        viewer.value.destroy()
      }
      // 清理键盘导航事件监听
      document.removeEventListener('keydown', handleKeyDown)
      // 清理预加载缓存，防止内存泄漏
      preloadedImages.value.clear()
      preloadQueue.value = []
      isPreloading.value = false
    })

    // 封装音频播放/暂停方法，暴露给父组件
    const toggleVrAudioPlayback = () => {
      console.log('音频功能已迁移至AudioPlayer组件')
      // 实际音频控制现在由App.vue中的AudioPlayer组件处理
    }
    
    // 定期清理预加载缓存，防止内存泄漏
    const scheduleCleanup = () => {
      // 在每次页面切换和索引变化后清理
      cleanupPreloadedImages()
    }
    
    // 监听页面切换或索引变化，进行缓存清理
    watch([currentIndex, currentPage], () => {
      scheduleCleanup()
    })

    // 暴露方法给父组件
    return {
      viewer,
      vrData,
      currentIndex,
      currentPage,
      pageSize,
      totalItems,
      showPreviousVR,
      showNextVR,
      showVRById,
      loadVRData,
      toggleAudioPlayback: toggleVrAudioPlayback,
      // 暴露预加载相关方法供调试和监控使用
      preloadedImages,
      preloadQueue,
      isPreloading,
      preloadAdjacentImages
    }
  }
}
</script>

<style scoped>
.viewer-container {
  width: 100vw;
  height: 100vh;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
}

.error-message {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 20px;
  border-radius: 8px;
  text-align: center;
  z-index: 1000;
  max-width: 500px;
}

.error-message h3 {
  color: #ff6b6b;
  margin-bottom: 10px;
}

.error-message p {
  margin-bottom: 15px;
}
</style>